import { _decorator, CCInteger, Component, Vec2, Vec3, instantiate, Label, Node, Prefab, input, Input, EventTouch,  NodePool, UITransform, Collider2D, v2, tween, Widget, view, Camera, find, utils} from 'cc';
import { BLOCK_SIZE, PlayerController } from './PlayerController';
import { EnemyType, GameConstants, GameState } from './constants/GameConstants';
import { Utils } from './common/CocosUtils';
import { global } from './common/Global';

const { ccclass, property } = _decorator;
@ccclass('GameManager')
export class GameManager extends Component {

    private static instance: GameManager = null;
    public static get Instance(): GameManager {
        return GameManager.instance;
    }

    // UI界面
    @property({ type: Node })
    public home: Node | null = null; // 游戏首页UI
    @property({ type: Node })
    public MapUI: Node | null = null; // 地图UI
    private mapWidth: number = 0;
    private mapHeight: number = 0;
  
    // 敌人
    @property({type: Prefab})
    public boxPrefab: Prefab|null = null;
    private enemyPool: NodePool =  null;
    private enemyGenCount: number = 20
    private enemyPos: Vec2 = new Vec2(0,0)
    private enemyPositions = new Set();
    
    // 爆炸火花
    @property({type: Prefab})
    public sparkPrefab: Prefab|null = null;
    private sparkPool: NodePool =  null;
    public sparkGenCount: number = 50;
    // 道具
    @property({type: Prefab})
    public propPrefab: Prefab|null = null;
    private propPool: NodePool =  null;
    public propGenCount: number = 10;
    
    @property({ type: PlayerController }) 
    public playerCtrl: PlayerController | null = null; // 角色控制器


    // 当前游戏状态
    private gameState:GameState = null;

    start() {
        // 监听接收
        this.playerCtrl?.node.on('genSpark', this.genSpark, this);
    }

    onLoad(){
        if (GameManager.instance === null) {
            GameManager.instance = this;
        } 

        this.setGameState(GameState.GS_INIT); 
        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);

         // 获取地图尺寸
         const map = this.node.parent.getChildByName('MapUI').getComponent(UITransform).contentSize;
         this.mapWidth = map.width;
         this.mapHeight = map.height;

        // 初始化敌人对象池
        this.initEnemyPool(this.boxPrefab)
        // 初始化火花对象池
        this.initSparkPool(this.sparkPrefab)
         // 初始化道具对象池
        this.initPropPool(this.propPrefab)
    }

    onTouchStart(event: EventTouch) {
       if(this.gameState == GameState.GS_INIT){
            console.log("开始游戏")
           this.setGameState(GameState.GS_START)
       }
    }

    setGameState (value: GameState) {
        this.gameState = value;
        switch(value) {
            case GameState.GS_INIT:    
                this.init();        
                break;
            case GameState.GS_START:
                this.gameStart();           
                break;    
            case GameState.GS_PLAYING:
                this.playing();           
                break;
            case GameState.GS_STOP:
                this.stop();           
                break;        
            case GameState.GS_END:
                break;
        }
    }


   

    /**
     * 游戏初始化
     */
    init(){
        // 开始UI
        this.home.active = true;
        this.MapUI.active = false;
        // 重设角色的位置和状态
        if (this.playerCtrl) {
            this.playerCtrl.setInputActive(false);
            this.playerCtrl.node.setPosition(Vec3.ZERO);
            this.playerCtrl.reset();
        }
        console.log("游戏初始化完成")
    }


    /**
     * 开始游戏
     */
    gameStart(){
        console.log("开始游戏")
        this.home.active = false;
        this.MapUI.active = true;
        //直接设置active会直接开始监听鼠标事件，做了一下延迟处理
        this.setGameState(GameState.GS_PLAYING)
    }

    /**
     * 继续游戏
     */
    playing(){
       setTimeout(() => {      
            if (this.playerCtrl) {
                this.playerCtrl.setInputActive(true);
            }
        }, 0.1);
    }

     /**
     * 暂停游戏
     */
    stop(){
        this.playerCtrl.setInputActive(false);
    }

    initEnemyPool(boxPrefab: Prefab) {
        this.enemyPool = new NodePool();
        this.initPool(boxPrefab, this.enemyPool, this.enemyGenCount)
        console.log("初始化敌人对象池完成")
    }
    initSparkPool(sparkPrefab: Prefab) {
       this.sparkPool = new NodePool();
       this.initPool(sparkPrefab, this.sparkPool, this.sparkGenCount)
       console.log("初始化火花对象池完成")
    }
    initPropPool(propPrefab: Prefab) {
       this.propPool = new NodePool();
       this.initPool(propPrefab, this.propPool, this.propGenCount)
       console.log("初始化道具对象池完成")
    }
    initPool(prefab: Prefab, pool: NodePool, initCount:number){
        for (let i = 0; i < initCount; ++i) {
            pool.put(instantiate(prefab)); 
        }
    }


     /**
     * 创建敌人
     * @param {*} enemyType  敌人类型
     * @param {*} enemyType  敌人类型
     */
    generateEnemy(enemyType:EnemyType, mapWidth:number, mapHeight:number, parentNode:Node){
        let newEnemy = null
        let name = 'box1'
        let hp = 1;
        //生成敌人一
        // if(enemyType == GameConstants.EnemyType_1){
            newEnemy = this.enemyPool.size() > 0 ? this.enemyPool.get() : instantiate(this.boxPrefab);
            let tag = 1;
            // 随机生成不同的敌人
            const num = Math.floor(Math.random() * 100) + 1;
            if(num > 90){
                name = 'box5'
                tag = 5
                hp = 5
            }else if(num > 80){
                name = 'box4'
                tag = 4
                hp = 4
            }else if (num > 70){
                name = 'box3'
                tag = 3
                hp = 3
            }else if (num > 40){
                name = 'box2'
                tag = 2
                hp = 2
            }else{
                name = 'box1'
                tag = 1
                hp = 1
            }
        Utils.setSpriteAtlas(newEnemy, 'plist/box', name)
        newEnemy.getComponent(Collider2D).tag = tag
        let ts = newEnemy.getComponent('Box')
        if(ts){
            ts.setHp(hp);
        }

        // }
        let randomX, randomY, positionKey;
        do {
            randomX = Math.random() * mapWidth - mapWidth / 2; // 随机生成 X 坐标
            randomY = Math.random() * mapHeight - mapHeight / 2; // 随机生成 Y 坐标
            positionKey = `${randomX},${randomY}`; // 创建唯一的位置键
            this.enemyPos.x = randomX
            this.enemyPos.y = randomY
        } while (this.enemyPositions.has(positionKey)); // 检查位置是否已存在
        if(newEnemy){
            parentNode.addChild(newEnemy);
            newEnemy.setPosition(this.enemyPos.x, this.enemyPos.y,0)
            global.enemyCount++;
        }
    }


    /**
     * 创建撞击火花
     */
    genSpark(otherNode: Node){
        let newfab = null;
        newfab = this.sparkPool.size() > 0 ? this.sparkPool.get() : instantiate(this.sparkPrefab);
        this.node.addChild(newfab);
        // 设置随机出现的位置，需要再node范围内
        let pos = otherNode.getPosition();
        const enemyUI = otherNode.getComponent(UITransform).contentSize;
        const xb = enemyUI.width;
        const yb = enemyUI.height;
        let x =  pos.x + Math.floor(Math.random() * xb) - xb/2;
        let y =  pos.y + Math.floor(Math.random() * yb) - yb/2;
        newfab.setPosition(x, y)
        let js = newfab.getComponent('Spark');
        if(js){
            js.trySpark()
        }
    }


     /**
     * 创建道具
     */
    createProp(node: Node, type: number){
        let newfab = null;
        newfab = this.propPool.size() > 0 ? this.propPool.get() : instantiate(this.propPrefab);
        this.node.addChild(newfab);
        newfab.getComponent(Collider2D).tag = 1000+type;
        newfab.getChildByName("Label").getComponent(Label).string = "+"+type;
        newfab.setPosition(node.getPosition())
    }

     //对象池回收
    delPrefab(fab: Node, fabType:number) {
        if(fabType == 0){
            this.sparkPool.put(fab);  //回收火花
        }
        if(fabType == 1){
            this.enemyPool.put(fab);  //回收敌人
        }
        if(fabType == 3){
            this.propPool.put(fab);  //回收敌人
        }
    }



     update(dt: number) {
        //创造敌人
        if(this.gameState == GameState.GS_PLAYING){ 
            if(global.enemyCount <= 3){
                console.log("enemyCount <= 3，生成敌人···")
                var enemyNum = Math.floor(Math.random() * 10 + 1)  //随机生成数量 (1 至 enemyCount)
                for (let i = 0; i < enemyNum; i++) {
                    this.generateEnemy(EnemyType.ADMIN, this.mapWidth, this.mapHeight, this.node)
                }
            }
        }

    }

    

}

